﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef LineEdit_h__
#define LineEdit_h__

#include "Widget.h"
#include "../utility/SmartPtrDef.h"
#include <memory>
#include <vector>

namespace SkyEngine2d
{
	
	class Text;
	class EventCharacter;
	class Scale9Image;
	
	/*!
	 \brief 单文本文本框
	*/
	class SGE_API LineEdit
		:public Widget
	{
	
		UI_CLASS(LineEdit)
	
	public:
		//! 创建一个单文本控件
		/*!
		\param const LineEditSharedPtr & parent 父控件
		\return LineEditSharedPtr
		*/
		static LineEdit* create(Widget* = nullptr);
	
		//! 创建一个单文本框控件 
		/*!
		\param const std::wstring & background_img  控件的背景图片
		\param const Rect & cap_insets 背景图片的可拉伸区域
		\param const LineEditSharedPtr & parent 父控件
		\return LineEditSharedPtr
		如果 cap_insets 为默认参数 则图片的可拉伸区域为图片的1/3 ，参考 Scale9Image 。
		*/
		static LineEdit* create(const std::wstring& background_img, const Rect& cap_insets = Rect::Zero, Widget*  parent = nullptr);
	
		//! 析构
		~LineEdit();
	
		//! 设置选中的区域
		/*!
		\param int start_pos 开始的位置
		\param int end_pos 结束的位置
		\return void
		选中的是一个 [start_pos,end_pos) 区域
		*/
		void setSelection(int start_pos, int end_pos);
	
		//! 清空选中的区域
		/*!
		\return void
		*/
		void clearSelection();
	
		//! 获取选中区域的长度
		/*!
		\return int
		*/
		int  getSelectionLen();
	
		//! 根据坐标获取文本的索引
		/*!
		\param const Vector2 & pos 坐标
		\return int
		*/
		int	 getTextIndexByPostion(const Vector2& pos);
	
		//! 设置当前光标的位置
		/*!
		\param int index 文本的索引位置
		\return void
		*/
		void setAnchorIndex(int index);
	
		//! 获取文本
		/*!
		\return const std::wstring&
		*/
		const std::wstring& getText()const;
	
		//! 设置文本
		/*!
		\param const std::wstring & text
		\return void
		*/
		void setText(const std::wstring& text);
	
		//! 设置掩码字符
		/*!
		\param wchar_t ch 字符
		\return void
		*/
		void setMaskChar(wchar_t ch);
	
	
	protected:
	
		LineEdit(Widget* parent);
	
		bool init(const std::wstring& background_img, const Rect& cap_insets = Rect::Zero);
	
		virtual void onKeyPressEvent(EventKey* event) override;
	
		virtual void onKeyReleaseEvent(EventKey* event) override;
	
		virtual void onMousePressEvent(EventMouse* event) override;
	
		virtual void onMouseReleaseEvent(EventMouse* event) override;
	
		virtual void onMouseMoveEvent(EventMouse* event) override;
	
		virtual void onCharacterEvent(EventCharacter* e) override;
	
		void displayerCursor(IRender* render);
	
		void displaySelection(IRender* render);
	
		float getPosXByIndex(int index);
	
		float getCharWidth(wchar_t ch);
	
		//处理退格键
		void handleBackspace();
		//处理左右箭头
		void handleArrow(int key);
		//移动光标
		void moveCursorL(int n = 1);
		void moveCursorR(int n = 1);
	
		virtual void onResizeEvent(EventResize* e) override;
	
		virtual void onMoveEvent(EventWidgetMove* e) override;
		virtual void draw(IRender* render, const Matrix4X4& transform) override;
	
	private:
		bool			m_isReadOnly;
		bool			m_isMaskText;
		wchar_t			m_maskCode;   /*!< 掩码的字符 . */
		int				m_maxTextLen; /*!< 最大的字符长度. */
		int				m_currentAnchorIdx; /*!< 当前输入光标的位置. */
		int				m_dragAnchorIdx;	/*!< 开始拖动鼠标的位置. */
		int				m_selectionStart;  /*!< 文字被选择的开始位置. */
		int				m_selectionEnd;  /*!< 文字被选择的结束位置. */
		bool			m_isBeginSelectText; /*!< 是否开始选择文字. */
		int				m_textLen;			/*!< 当前的文本长度. */
		std::wstring	m_text;	 /*!< 文本字符串. */
	
		Scale9Image* m_currentBgImag;  /*!< 当前的背景图. */
		std::unique_ptr<Text>			m_textRender;
	
		//选区相关的 
		Rect	m_selectionRect;    /*!< 选中的区域. */
	
		// 光标相关的
		int			m_drawCount;		/*!<. 渲染的计数 用来 判断光标应不应该显示*/
		Vector2		m_cursorPosStart;
		Vector2     m_cursorPosEnd;
	
	private:
		virtual int getDefultWidth() const override;
		virtual int getDefultHeight() const override;
		virtual void onWidgetStateChange() override;
		virtual void onWidgetStyleChange() override;
		void updateStyleInfo();
	};
	
}

#endif // LineEdit_h__
